﻿using System;
using System.ComponentModel;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using Kay.Communication.Framework.Custom_EventArgs;

namespace Kay.Communication.Framework
{
    /// <summary>
    /// Udp 客户端
    /// </summary>
    public class UdpInterNetworkDgramClient
    {
        private BaseCommunication Client { get; set; }

        /// <summary>
        /// 通信使用的参数
        /// </summary>
        public CommunicationArgs CommunicationArgs { get; private set; }

        /// <summary>
        /// Udp 使用的端口
        /// </summary>
        public ushort Port { get; private set; }

        /// <summary>
        /// 初始化 Udp 客户端
        /// </summary>
        /// <param name="ip">需要绑定的 Ip</param>
        /// <param name="port">需要绑定的端口</param>
        /// <exception cref="ArgumentNullException">如果 IP 为 null，将引发异常</exception>
        public UdpInterNetworkDgramClient(string ip, ushort port)
        {
            if (ip == null)
                throw new ArgumentNullException("ip");

            Port = port;
            Client = new BaseCommunication();
            Client.UdpMessageReceived += OnClientUdpMessageReceived;
            CommunicationArgs = new CommunicationArgs
            {
                Encoding = Encoding.UTF8,
                AddressFamily = AddressFamily.InterNetwork,
                EndPoint = new IPEndPoint(IPAddress.Parse(ip), port),
                MessageLength = 1024 * 1000,
                ProtocolType = ProtocolType.Udp,
                CommunicationMode = CommunicationModes.UdpClient,
                SocketType = SocketType.Dgram,
                Waiting = 10000,
                UdpDataLength = 2048
            };
            Client.InitializeBaseCommunication(CommunicationArgs);
        }

        private void OnClientUdpMessageReceived(object sender, UdpMessageReceivedEventArgs e)
        {
            var sb = new StringBuilder();
            var infos = e.Info.OrderBy(n => n.Index).ToList();
            infos.ForEach(n => sb.Append(CommunicationArgs.Encoding.GetString(n.Bytes)));
            var user = new ContactsInfo
            {
                RemoteEndPointByClient = e.RemoteEndPoint.ToString()
            };
            if (TextMessageReceived != null)
            {
                TextMessageReceived.Invoke(this, new TextMessageReceivedEventArgs(user, sb.ToString()));
            }
        }

        /// <summary>
        /// 启动 Udp 客户端
        /// </summary>
        public void Start()
        {
            Client.InitializeUdpClient();
        }

        /// <summary>
        /// 停止 Udp 客户端
        /// </summary>
        public void Stop()
        {
            Client.Close();
            Client.InitializeBaseCommunication(CommunicationArgs);
        }

        /// <summary>
        /// 发送文本消息
        /// </summary>
        /// <param name="ip">接收者 IP</param>
        /// <param name="value">文本</param>
        public void SendTextMessage(IPAddress ip, string value)
        {
            Client.SendUdpMessage(new IPEndPoint(ip, Port), CommunicationArgs.Encoding.GetBytes(value));
        }

        /// <summary>
        /// 收到文本消息事件
        /// </summary>
        [Description("当收到文本消息时发生")]
        public event EventHandler<TextMessageReceivedEventArgs> TextMessageReceived;
    }
}